
package com.feib.soeasy.security;

import java.util.Collection;

import java.util.Iterator;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;

/**
 * @title (#)SoeasyAccessDecisionManager.java<br>
 * @description <br>
 * @author Anson Tsai<br>
 * @version 1.0.0 2010/11/25
 * @copyright Far Eastern International Bank Copyright (c) 2010<br>
 * @2010/11/30 create by Anson Tsai<br>
 */
@Service("SoeasyAccessDecisionManager")
public class SoeasyAccessDecisionManager implements AccessDecisionManager {

    private static final Logger logger = LoggerFactory.getLogger(SoeasyAccessDecisionManager.class);

    /*
     * authentication : 為用戶本身自已的權限
     * configAttributes : 為此之傳入之URL的權限
     * 
     * @see
     * org.springframework.security.access.AccessDecisionManager#decide(org.
     * springframework.security.core.Authentication , java.lang.Object,
     * java.util.Collection)
     */
    @Override
    public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)
                    throws AccessDeniedException, InsufficientAuthenticationException {
        if (logger.isDebugEnabled()) {
            logger.trace("decide(Authentication, Object, Collection<ConfigAttribute>) - start");
        }
        if (null == configAttributes) {
            if (logger.isDebugEnabled()) {
                logger.trace("configAttributes is null");
            }
            return;
        }
        if (logger.isDebugEnabled()) {
            logger.trace("正在訪問的url是：" + object.toString());
        }
        Iterator<ConfigAttribute> ite = configAttributes.iterator();
        while (ite.hasNext()) {
            ConfigAttribute ca = ite.next();
            logger.trace("need Role is : " + ca.getAttribute());
            String needRole = ((SecurityConfig) ca).getAttribute();
            for (GrantedAuthority ga : authentication.getAuthorities()) {
                logger.trace("判斷到,此訪問的url need role : " + needRole + ",用戶的角色 : " + ga.getAuthority());
                if (needRole.equals(ga.getAuthority())) {
                    // ga is user's role.
                    if (logger.isDebugEnabled()) {
                        logger.trace("判斷到,授權數據相配");
                        logger.trace("decide(Authentication, Object, Collection<ConfigAttribute>) - end");
                    }
                    return;
                }
                logger.trace("判斷到，授權數據不相匹配");
            }
        }
        if (logger.isDebugEnabled()) {
            logger.trace("decide(Authentication, Object, Collection<ConfigAttribute>) - end");
        }
        throw new AccessDeniedException("No authentication");
    }

    /*
     * (non-Javdoc)
     * 
     * @see
     * org.springframework.security.access.AccessDecisionManager#supports(org
     * .springframework.security.access. ConfigAttribute)
     */
    @Override
    public boolean supports(ConfigAttribute arg0) {
        // TODO 自動產生方法 Stub
        return true;
    }

    /*
     * (non-Javdoc)
     * 
     * @see
     * org.springframework.security.access.AccessDecisionManager#supports(java
     * .lang.Class)
     */
    @Override
    public boolean supports(Class<?> arg0) {
        // TODO 自動產生方法 Stub
        return true;
    }

}
